home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / perl / os2perl / array.c < prev    next >
C/C++ Source or Header  |  1991-06-11  |  6KB  |  268 lines

  1. /* $RCSfile: array.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 10:19:08 $
  2.  *
  3.  *    Copyright (c) 1991, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    array.c,v $
  9.  * Revision 4.0.1.1  91/06/07  10:19:08  lwall
  10.  * patch4: new copyright notice
  11.  *
  12.  * Revision 4.0  91/03/20  01:03:32  lwall
  13.  * 4.0 baseline.
  14.  *
  15.  */
  16.  
  17. #include "EXTERN.h"
  18. #include "perl.h"
  19.  
  20. STR *
  21. afetch(ar,key,lval)
  22. register ARRAY *ar;
  23. int key;
  24. int lval;
  25. {
  26.     STR *str;
  27.  
  28.     if (key < 0 || key > ar->ary_fill) {
  29.     if (lval && key >= 0) {
  30.         if (ar->ary_flags & ARF_REAL)
  31.         str = Str_new(5,0);
  32.         else
  33.         str = str_mortal(&str_undef);
  34.         (void)astore(ar,key,str);
  35.         return str;
  36.     }
  37.     else
  38.         return &str_undef;
  39.     }
  40.     if (!ar->ary_array[key]) {
  41.     if (lval) {
  42.         str = Str_new(6,0);
  43.         (void)astore(ar,key,str);
  44.         return str;
  45.     }
  46.     return &str_undef;
  47.     }
  48.     return ar->ary_array[key];
  49. }
  50.  
  51. bool
  52. astore(ar,key,val)
  53. register ARRAY *ar;
  54. int key;
  55. STR *val;
  56. {
  57.     int retval;
  58.  
  59.     if (key < 0)
  60.     return FALSE;
  61.     if (key > ar->ary_max) {
  62.     int newmax;
  63.  
  64.     if (ar->ary_alloc != ar->ary_array) {
  65.         retval = ar->ary_array - ar->ary_alloc;
  66.         Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
  67.         Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
  68.         ar->ary_max += retval;
  69.         ar->ary_array -= retval;
  70.         if (key > ar->ary_max - 10) {
  71.         newmax = key + ar->ary_max;
  72.         goto resize;
  73.         }
  74.     }
  75.     else {
  76.         if (ar->ary_alloc) {
  77.         newmax = key + ar->ary_max / 5;
  78.           resize:
  79.         Renew(ar->ary_alloc,newmax+1, STR*);
  80.         Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
  81.         }
  82.         else {
  83.         newmax = key < 4 ? 4 : key;
  84.         Newz(2,ar->ary_alloc, newmax+1, STR*);
  85.         }
  86.         ar->ary_array = ar->ary_alloc;
  87.         ar->ary_max = newmax;
  88.     }
  89.     }
  90.     if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
  91.     while (++ar->ary_fill < key) {
  92.         if (ar->ary_array[ar->ary_fill] != Nullstr) {
  93.         str_free(ar->ary_array[ar->ary_fill]);
  94.         ar->ary_array[ar->ary_fill] = Nullstr;
  95.         }
  96.     }
  97.     }
  98.     retval = (ar->ary_array[key] != Nullstr);
  99.     if (retval && (ar->ary_flags & ARF_REAL))
  100.     str_free(ar->ary_array[key]);
  101.     ar->ary_array[key] = val;
  102.     return retval;
  103. }
  104.  
  105. ARRAY *
  106. anew(stab)
  107. STAB *stab;
  108. {
  109.     register ARRAY *ar;
  110.  
  111.     New(1,ar,1,ARRAY);
  112.     ar->ary_magic = Str_new(7,0);
  113.     ar->ary_alloc = ar->ary_array = 0;
  114.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  115.     ar->ary_max = ar->ary_fill = -1;
  116.     ar->ary_flags = ARF_REAL;
  117.     return ar;
  118. }
  119.  
  120. ARRAY *
  121. afake(stab,size,strp)
  122. STAB *stab;
  123. register int size;
  124. register STR **strp;
  125. {
  126.     register ARRAY *ar;
  127.  
  128.     New(3,ar,1,ARRAY);
  129.     New(4,ar->ary_alloc,size+1,STR*);
  130.     Copy(strp,ar->ary_alloc,size,STR*);
  131.     ar->ary_array = ar->ary_alloc;
  132.     ar->ary_magic = Str_new(8,0);
  133.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  134.     ar->ary_fill = size - 1;
  135.     ar->ary_max = size - 1;
  136.     ar->ary_flags = 0;
  137.     while (size--) {
  138.     (*strp++)->str_pok &= ~SP_TEMP;
  139.     }
  140.     return ar;
  141. }
  142.  
  143. void
  144. aclear(ar)
  145. register ARRAY *ar;
  146. {
  147.     register int key;
  148.  
  149.     if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
  150.     return;
  151.     if (key = ar->ary_array - ar->ary_alloc) {
  152.     ar->ary_max += key;
  153.     ar->ary_array -= key;
  154.     }
  155.     for (key = 0; key <= ar->ary_max; key++)
  156.     str_free(ar->ary_array[key]);
  157.     ar->ary_fill = -1;
  158.     Zero(ar->ary_array, ar->ary_max+1, STR*);
  159. }
  160.  
  161. void
  162. afree(ar)
  163. register ARRAY *ar;
  164. {
  165.     register int key;
  166.  
  167.     if (!ar)
  168.     return;
  169.     if (key = ar->ary_array - ar->ary_alloc) {
  170.     ar->ary_max += key;
  171.     ar->ary_array -= key;
  172.     }
  173.     if (ar->ary_flags & ARF_REAL) {
  174.     for (key = 0; key <= ar->ary_max; key++)
  175.         str_free(ar->ary_array[key]);
  176.     }
  177.     str_free(ar->ary_magic);
  178.     Safefree(ar->ary_alloc);
  179.     Safefree(ar);
  180. }
  181.  
  182. bool
  183. apush(ar,val)
  184. register ARRAY *ar;
  185. STR *val;
  186. {
  187.     return astore(ar,++(ar->ary_fill),val);
  188. }
  189.  
  190. STR *
  191. apop(ar)
  192. register ARRAY *ar;
  193. {
  194.     STR *retval;
  195.  
  196.     if (ar->ary_fill < 0)
  197.     return Nullstr;
  198.     retval = ar->ary_array[ar->ary_fill];
  199.     ar->ary_array[ar->ary_fill--] = Nullstr;
  200.     return retval;
  201. }
  202.  
  203. aunshift(ar,num)
  204. register ARRAY *ar;
  205. register int num;
  206. {
  207.     register int i;
  208.     register STR **sstr,**dstr;
  209.  
  210.     if (num <= 0)
  211.     return;
  212.     if (ar->ary_array - ar->ary_alloc >= num) {
  213.     ar->ary_max += num;
  214.     ar->ary_fill += num;
  215.     while (num--)
  216.         *--ar->ary_array = Nullstr;
  217.     }
  218.     else {
  219.     (void)astore(ar,ar->ary_fill+num,(STR*)0);    /* maybe extend array */
  220.     dstr = ar->ary_array + ar->ary_fill;
  221.     sstr = dstr - num;
  222. #ifdef BUGGY_MSC5
  223.  # pragma loop_opt(off)    /* don't loop-optimize the following code */
  224. #endif /* BUGGY_MSC5 */
  225.     for (i = ar->ary_fill; i >= 0; i--) {
  226.         *dstr-- = *sstr--;
  227. #ifdef BUGGY_MSC5
  228.  # pragma loop_opt()    /* loop-optimization back to command-line setting */
  229. #endif /* BUGGY_MSC5 */
  230.     }
  231.     Zero(ar->ary_array, num, STR*);
  232.     }
  233. }
  234.  
  235. STR *
  236. ashift(ar)
  237. register ARRAY *ar;
  238. {
  239.     STR *retval;
  240.  
  241.     if (ar->ary_fill < 0)
  242.     return Nullstr;
  243.     retval = *ar->ary_array;
  244.     *(ar->ary_array++) = Nullstr;
  245.     ar->ary_max--;
  246.     ar->ary_fill--;
  247.     return retval;
  248. }
  249.  
  250. int
  251. alen(ar)
  252. register ARRAY *ar;
  253. {
  254.     return ar->ary_fill;
  255. }
  256.  
  257. afill(ar, fill)
  258. register ARRAY *ar;
  259. int fill;
  260. {
  261.     if (fill < 0)
  262.     fill = -1;
  263.     if (fill <= ar->ary_max)
  264.     ar->ary_fill = fill;
  265.     else
  266.     (void)astore(ar,fill,Nullstr);
  267. }
  268.